import enum
from math import floor

from fastapi import Query, HTTPException
from fastapi.responses import StreamingResponse
from fastapi import APIRouter
from tortoise.expressions import RawSQL, Q, Case, When
from tortoise.fields import IntField

from src.db import db_models

paper_router = APIRouter()


@paper_router.get("/")
async def get_paper_list():
    return await db_models.Papers.filter(is_valid=True).all()


#分数分配算法
async def score_allocate(score: int, ques: str):
    score = int(score)
    ques = ques.replace('，', ',').replace("'", '')
    ques_list = [int(i) for i in ques.split(',')]

    low_list = await (db_models.Questions
                      .filter(id__in=ques_list, leixing__in=['选择题', '判断题'])
                      .values('id', 'tigan'))

    mid_list = await (db_models.Questions
                      .filter(id__in=ques_list, leixing='填空题')
                      .values('id', 'tigan'))

    high_list = await (db_models.Questions
                       .filter(id__in=ques_list, leixing='简答题')
                       .annotate(
        sort_order=Case(
            When(nandu__in=['简单', '简单难度'], then='1'),
            When(nandu__in=['一般', '一般难度'], then='2'),
            When(nandu__in=['困难', '困难难度'], then='3'),
            default='0'
        )
    )
                       .order_by('sort_order')
                       .values('id', 'tigan'))

    a = len(low_list) + len(mid_list) * 2 + len(high_list) * 4
    if score<a:
        raise HTTPException(422, '分值设置太低，请重新设置一个合理的分数')
    low_score = score // a
    mid_score = (score * 2) // a
    high_score = (score - low_score * len(low_list) - mid_score * len(mid_list)) // len(high_list)/2
    extra_score = score - low_score * len(low_list) - mid_score * len(mid_list) - high_score * len(high_list)
    list1 = [{'question_id_id': i['id'], 'score': low_score} for i in low_list]
    list2 = [{'question_id_id': i['id'], 'score': mid_score} for i in mid_list]
    list3 = [{'question_id_id': i['id'], 'score': high_score} for i in high_list]
    list3[-1]['score'] += extra_score
    return list1 + list2 + list3


class Assign_Scores(enum.Enum):
    auto='AUTO'
    manual='MANUAL'

#paper表和paper_detail表同时插入，更新试卷
@paper_router.post("/")
async def add_paper(paper_id, name, desc, author,assign_score: Assign_Scores, score, ques):
    if assign_score == Assign_Scores.auto:
        paper = await db_models.Papers.create(id=paper_id,
                                              name=name,
                                              desc=desc,
                                              author=author,
                                              score=score)

        a = await score_allocate(score, ques)
        paper_detail = await db_models.Paper_Detail.bulk_create(
            [
                db_models.Paper_Detail(
                    paper_id_id=paper_id,
                    question_id_id=data['question_id_id'],
                    score=data['score']
                )
                for data in a
            ]
        )
    else:
        score = score.replace('，', ',').replace("'", '')
        score_list = [int(i) for i in score.split(',')]
        ques = ques.replace('，', ',').replace("'", '')
        ques_list = [int(i) for i in ques.split(',')]

        paper = await db_models.Papers.create(id=paper_id,
                                              name=name,
                                              desc=desc,
                                              author=author,
                                              score=sum(score))
        paper_detail = await db_models.Paper_Detail.bulk_create(
            [
                db_models.Paper_Detail(
                    paper_id_id=paper_id,
                    question_id_id=ques_list[i],
                    score=score_list[i]
                )
                for i in range(len(score_list))
            ]
        )
    return paper_detail
